#!/usr/bin/python

import abc
import logging
import string

import globals as sys_globals

from abc import abstractmethod
from loader import Loader
from globals import models_pkg_path
from globals import libraries_pkg_path

"""
    class      : service
    description : a base class for all timer service
"""
class BaseService(object):
    """
    id: scheduler job id
    """
    _id = 0

    """
    arguments: argument for service to handle
    """
    _arguments = {}

    """
    loader: model, library class or function loader
    """
    _loader = None

    """
    config: service configuration
    """
    _config = None

    """
    logger: service event logger
    """
    _logger = None

    """
    dbSession: database session for service model
    """
    _dbSession = None

    """
    constructor: constructor for apscheduler service
    """
    def __init__(self, id = 0, arguments = None):

        self._id        = id
        self._arguments = arguments

        """
        Initialize loader and get loader items
        """
        self._loader    = Loader()
        self._loader.initialize()
        items = self._loader.get_loader_items()

        self._config    = items['config']
        self._dbSession = items['dbSession']
        self._logger    = items['event_logger']
                
        return


    """
    load_model: use loader to load model class
    """
    def load_model(self, model):
        if self._loader is not None:
            package_path     = model.split('.')
            module_name      = sys_globals.models_pkg_path + "." + string.join(package_path[0:-1], ".")
            class_name       = package_path[-1]
            class_model_name = "%s_model" % (class_name.lower())
            if not hasattr(self, class_model_name):
                cls = self._loader.model(module_name, class_name)
                instance = cls(self._dbSession)
                setattr(self, class_model_name, instance)
        return


    """
    load_librairy: use loader to load library class
    """
    def load_library(self, library, params = None):
        if self._loader is not None:
            package_path = library.split('.')
            module_name  = sys_globals.libraries_pkg_path + "." + string.join(package_path[0:-1], ".")
            class_name   = package_path[-1]
            if not hasattr(self, class_name.lower()):
                cls = self._loader.library(module_name, class_name)
                if params is not None:
                    instance = cls(params)
                else:
                    instance = cls()
                setattr(self, class_name.lower(), instance)
        return


    """
    log_error: log error message
    """
    def log_error(self, message):
        if self._logger is not None:
            self._logger.log_error(message)
        return


    """
    log_info: log information message
    """
    def log_info(self, message):
        if self._logger is not None:
            self._logger.log_info(message)
        return


    """
    log_debug: log debug message
    """
    def log_debug(self, message):
        if self._logger is not None:
            self._logger.log_debug(message)
        return


    """
    log_warning: log warining message
    """
    def log_warning(self, message):
        if self._logger is not None:
            self._logger.log_warining(message)
        return


    """
    log_critical: log critical message
    """
    def log_critical(self, message):
        if self._logger is not None:
            self._logger.log_critical(message)
        return


    """
    release_resource: release resource for service
    """
    def release_resource(self):
        self._loader.release_resource();
        return


    """
    invoke: a abstract interface for service to handle service transcation
    """
    @abstractmethod
    def invoke(self):
        pass
        return
